import winston from 'winston'
import DailyRotateFile from 'winston-daily-rotate-file'
import path from 'path'
import fs from 'fs'
import { BrowserWindow } from 'electron'
import { AppConfig } from '../config/app'

// 获取日志存储目录
const getLogDir = (): string => {
  let logDir = AppConfig.LOG.ROOT_DIR

  // 如果启用按天创建文件夹，添加日期文件夹
  if (AppConfig.LOG.DAILY_FOLDER) {
    const today = new Date().toISOString().split('T')[0] // YYYY-MM-DD
    logDir = path.join(logDir, today)
  }

  // 确保日志目录存在
  if (!fs.existsSync(logDir)) {
    fs.mkdirSync(logDir, { recursive: true })
  }

  return logDir
}

// 自定义日志格式
const logFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss'
  }),
  winston.format.errors({ stack: true }),
  winston.format.printf(({ timestamp, level, message, stack, ...meta }) => {
    let logMessage = `[${timestamp}] [${level.toUpperCase()}]`

    // 如果有进程信息，添加进程标识
    if (meta.process) {
      logMessage += ` [${meta.process}]`
    }

    logMessage += `: ${message}`

    // 如果有额外的元数据，添加到日志中
    const metaStr =
      Object.keys(meta).filter((key) => key !== 'process').length > 0
        ? ` ${JSON.stringify(meta)}`
        : ''

    return logMessage + metaStr + (stack ? `\n${stack}` : '')
  })
)

// 创建按天分割的文件传输器
const createFileTransport = (filename: string, level = 'info'): DailyRotateFile => {
  return new DailyRotateFile({
    filename: path.join(getLogDir(), `${filename}-%DATE%.log`),
    datePattern: AppConfig.LOG.DAILY_FOLDER ? 'YYYY-MM-DD' : 'YYYY-MM-DD',
    zippedArchive: AppConfig.LOG.ZIPPED_ARCHIVE,
    maxSize: AppConfig.LOG.MAX_SIZE,
    maxFiles: AppConfig.LOG.MAX_FILES,
    level: level,
    format: logFormat,
    // 禁用审计文件以避免生成那些JSON文件
    auditFile: AppConfig.LOG.AUDIT_FILE
      ? path.join(getLogDir(), `.${filename}-audit.json`)
      : undefined
  })
}

// 创建控制台专用格式（带颜色）
const consoleFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss'
  }),
  winston.format.errors({ stack: true }),
  winston.format.colorize(),
  winston.format.printf(({ timestamp, level, message, stack, ...meta }) => {
    let logMessage = `[${timestamp}] [${level}]`

    // 如果有进程信息，添加进程标识
    if (meta.process) {
      logMessage += ` [${meta.process}]`
    }

    logMessage += `: ${message}`

    // 如果有额外的元数据，添加到日志中
    const metaStr =
      Object.keys(meta).filter((key) => key !== 'process').length > 0
        ? ` ${JSON.stringify(meta)}`
        : ''

    return logMessage + metaStr + (stack ? `\n${stack}` : '')
  })
)

// 创建控制台传输器
const consoleTransport = new winston.transports.Console({
  level: AppConfig.LOG.LEVEL,
  format: consoleFormat
})

// 创建 IPC 传输器，将日志推送到渲染进程
class IPCTransport extends winston.transports.Stream {
  constructor(opts?: winston.transports.StreamTransportOptions) {
    super(opts)
  }

  log(info: winston.LogEntry, callback: () => void): void {
    // 获取所有窗口并发送日志
    const windows = BrowserWindow.getAllWindows()
    windows.forEach((win) => {
      if (win && !win.isDestroyed()) {
        win.webContents.send('log-message', {
          level: info.level,
          message: info.message,
          timestamp: info.timestamp,
          process: info.process || 'MAIN'
        })
      }
    })
    callback()
  }
}

// 创建 IPC 传输器实例
const ipcTransport = new IPCTransport({
  level: AppConfig.LOG.LEVEL,
  stream: process.stdout // 提供必需的 stream 属性
})

// 创建主logger实例
const logger = winston.createLogger({
  level: AppConfig.LOG.LEVEL,
  transports: [
    consoleTransport,
    ipcTransport, // 添加 IPC 传输器
    createFileTransport('main', AppConfig.LOG.LEVEL), // 主进程日志，使用配置的级别
    createFileTransport('error', 'error'), // 错误日志单独文件
    createFileTransport('combined', 'info') // 综合日志，只记录 info 及以上级别
  ],
  // 处理未捕获的异常和拒绝
  exceptionHandlers: [createFileTransport('exceptions', 'error')],
  rejectionHandlers: [createFileTransport('rejections', 'error')]
})

// 为主进程日志添加标识
const mainLogger = {
  debug: (message: unknown, meta?: Record<string, unknown>) =>
    logger.debug(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'MAIN',
      ...meta
    }),
  info: (message: unknown, meta?: Record<string, unknown>) =>
    logger.info(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'MAIN',
      ...meta
    }),
  warn: (message: unknown, meta?: Record<string, unknown>) =>
    logger.warn(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'MAIN',
      ...meta
    }),
  error: (message: unknown, meta?: Record<string, unknown>) =>
    logger.error(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'MAIN',
      ...meta
    })
}

// 为渲染进程日志添加标识
const rendererLogger = {
  debug: (message: unknown, meta?: Record<string, unknown>) =>
    logger.debug(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'RENDERER',
      ...meta
    }),
  info: (message: unknown, meta?: Record<string, unknown>) =>
    logger.info(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'RENDERER',
      ...meta
    }),
  warn: (message: unknown, meta?: Record<string, unknown>) =>
    logger.warn(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'RENDERER',
      ...meta
    }),
  error: (message: unknown, meta?: Record<string, unknown>) =>
    logger.error(typeof message === 'object' ? JSON.stringify(message) : String(message), {
      process: 'RENDERER',
      ...meta
    })
}

export { mainLogger, rendererLogger, logger }
export default mainLogger
